package org.atlantis.datasink.server.buildin;

import java.net.InetSocketAddress;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;

import org.atlantis.datasink.codec.ICodecContext;
import org.atlantis.datasink.server.AbstractCodecServer;
import org.atlantis.datasink.server.CommType;
import org.atlantis.datasink.utils.SimpleExecutor;
import org.jboss.netty.bootstrap.ServerBootstrap;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.group.ChannelGroup;
import org.jboss.netty.channel.group.DefaultChannelGroup;
import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class PassiveTCPServer extends AbstractCodecServer {

	private static final Logger log = LoggerFactory.getLogger(PassiveTCPServer.class);

	private List<ServerBootstrap> bootstraps = Collections.synchronizedList(new LinkedList<ServerBootstrap>());
	private ChannelGroup needToCloseGroup = new DefaultChannelGroup();
	private SimpleExecutor executor = new SimpleExecutor();

	@Override
	public CommType getCommType() {
		return CommType.PASSIVE;
	}

	@Override
	protected void startByCodec(ICodecContext codecCtx) {
		ServerBootstrap bootstrap = new ServerBootstrap(new NioServerSocketChannelFactory(executor, executor));
		bootstrap.setOption("keepAlive", true);
		bootstrap.setOption("tcpNoDelay", true);
		bootstrap.setPipelineFactory(createPipelineFactory(codecCtx));
		Channel serverChannel = bootstrap.bind(new InetSocketAddress(codecCtx.getOption().getBindPort()));
		needToCloseGroup.add(serverChannel);
		log.info(codecCtx.getCodec().getName() + " codec started. Listening on port: " + codecCtx.getOption().getBindPort());
		bootstraps.add(bootstrap);
	}

	@Override
	public void shutdown() {
		needToCloseGroup.close();
		for (ServerBootstrap bootstrap : bootstraps) {
			bootstrap.releaseExternalResources();
		}
		executor.destory();
	}

	@Override
	public String getName() {
		return "Passive-TCP-Server";
	}
}
